package blms.facade;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import blms.system.BLMS;
import blms.system.exception.LeagueDoesNotExistException;
import blms.system.exception.UnknownAttribute;
import blms.system.exception.UserDoesNotExistException;
import blms.system.exception.restrictions.RestrictionException;
import blms.system.manager.MatchesManager;
import blms.system.user.User;

/**
 * Facade that provides the methods to be performed by the test cases through easyaccept.
 *
 */
public class BLMSFacade {
	
	/**
	 * The system as a whole.
	 */
	private final BLMS blms = new BLMS();

	public BLMSFacade() {
		dateFormat("dd/MM/yyyy");
	}
	
	/**
	 * Indicates which database must be used by the system.
	 * @param dataBaseName The name of the database to be user
	 */
	public void useDatabase(String dataBaseName) {}
	
	/**
	 * EasyAccept facade for <code>BLMS.removeAllLeagues</code> method.
	 * 
	 * @see BLMS.removeAllLeagues
	 */
	public void removeAllLeagues(){
		blms.removeAllLeagues();
	}
	
	/**
	 * Removes all matches from BMLS system.
	 */
	public void removeAllMatches(){
		blms.removeAllMatches();
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.deleteMatch</code>
	 * 
	 * @see MatchesManager.deleteMatch
	 */
	public void deleteMatch(int matchID) {
		blms.deleteMatch(matchID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.removeAllUsers</code> method.
	 * 
	 * @see BLMS.removeAllUsers
	 */
	public void removeAllUsers(){
		blms.removeAllUsers();
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.findUserByLastName</code> method.
	 * 
	 * @see BLMS.findUserByLastName
	 */
	public List<String> findUserByLastName(String lastName) throws UserDoesNotExistException {
		return blms.findUserByLastName(lastName);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.createUser</code> method.
	 * 
	 * @see BLMS.createUser
	 */
	public String createUser(String firstName, String lastName, String homePhone, String workPhone, 
								String cellPhone, String email, File picture) throws RestrictionException {
		
		return blms.createUser(firstName, lastName, homePhone, workPhone, cellPhone, email, picture);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getUserAttribute</code> method.
	 * 
	 * @see BLMS.getUserAttribute
	 */
	public String getUserAttribute(String id, String attribute) throws UserDoesNotExistException, UnknownAttribute {
		return blms.getUserAttribute(id, attribute);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.changeUserAttribute</code> method.
	 * 
	 * @see BLMS.changeUserAttribute
	 */
	public void changeUserAttribute(String id, String attribute, String value) throws UserDoesNotExistException, UnknownAttribute, 
																						RestrictionException {
		blms.changeUserAttribute(id, attribute, value);
	}

	/**
	 * EasyAccept facade for <code>BLMS.deleteUser</code> method.
	 * 
	 * @see BLMS.deleteUser
	 */
	public void deleteUser(String id) throws RestrictionException, UserDoesNotExistException {
		blms.deleteUser(id);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.findLeague</code> method.
	 * 
	 * @see BLMS.findLeague
	 */
	public List<String> findLeague(String name) throws LeagueDoesNotExistException {
		return blms.findLeague(name);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.createLeague</code> method.
	 * @throws ParseException 
	 * 
	 * @see BLMS.createLeague
	 */
	public String createLeague(String name, String operator) throws RestrictionException, UserDoesNotExistException, ParseException {
		return blms.createLeague(name, operator, blms.getDateFormat().parse(todaysDate()));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getLeagueAttribute</code> method.
	 * 
	 * @see BLMS.getLeagueAttribute
	 */
	public String getLeagueAttribute(String leagueID,  String attribute) throws LeagueDoesNotExistException, UnknownAttribute {
		return blms.getLeagueAttribute(leagueID, attribute);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.changeLeagueAttribute</code> method.
	 * 
	 * @see BLMS.changeLeagueAttribute
	 */
	public void changeLeagueAttribute(String leagueID, String attribute, String value) throws RestrictionException,
																						LeagueDoesNotExistException,
																							UnknownAttribute,
																								UserDoesNotExistException {
		blms.changeLeagueAttribute(leagueID, attribute, value);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.deleteLeague</code> method.
	 * 
	 * @see BLMS.deleteLeague
	 */
	public void deleteLeague(String leagueID) throws RestrictionException {
		blms.deleteLeague(leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.isLeagueMember</code> method.
	 * 
	 * @see BLMS.isLeagueMember
	 */
	public boolean isLeagueMember(String userID, String leagueID) throws LeagueDoesNotExistException, 
																			UserDoesNotExistException, RestrictionException {
		return blms.isLeagueMember(userID, leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getPlayerLeagues</code> method.
	 * 
	 * @see BLMS.getPlayerLeagues
	 */
	public String getPlayerLeagues(String id) throws UserDoesNotExistException {
		String returnValue = this.blms.getPlayerLeagues(id).toString();
		return returnValue.substring(1,returnValue.length()-1);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getLeagueMembers</code> method.
	 * 
	 * @see BLMS.getLeagueMembers
	 */
	public String getLeagueMembers(String leagueID) throws LeagueDoesNotExistException {
		
		List<String> returnValue = new LinkedList<String>();
		
		Collection<User> leagueMembers = blms.getLeagueMembers(leagueID);
		
		for (User user : leagueMembers) {
			returnValue.add(user.getLastName());
		}
		// inefficient - inserir ordenando
		Collections.sort(returnValue);
		return returnValue.toString().substring(1,returnValue.toString().length()-1);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.joinLeague</code> method.
	 *
	 * @see BLMS.joinLeague
	 */
	public void joinLeague(String userID, String leagueID, String initialHandicap) throws LeagueDoesNotExistException,
																							UserDoesNotExistException,
																								RestrictionException { 
		
		blms.joinLeague(userID, leagueID, initialHandicap);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getUserLeagueAttribute</code> method.
	 *
	 * @see BLMS.getUserLeagueAttribute
	 */
	public String getUserLeagueAttribute(String userId, String leagueID, String attribute) throws LeagueDoesNotExistException,
																											RestrictionException,
																												UnknownAttribute,
																													UserDoesNotExistException {
		return blms.getUserLeagueAttribute(userId, leagueID, attribute).toString();
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.leaveLeague</code> method.
	 *
	 * @see BLMS.leaveLeague
	 */
	public void leaveLeague(String userID, String leagueID) throws UserDoesNotExistException, LeagueDoesNotExistException,
																		RestrictionException {
		blms.leaveLeague(userID, leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getNumberOfMatches</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getNumberOfMatches
	 */
	public int getNumberOfMatches(String leagueID) throws RestrictionException {
		return blms.getNumberOfMatches(leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getNumberOfMatches</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getNumberOfMatches
	 */
	public int getNumberOfMatches(String playerID, String leagueID) throws RestrictionException {
		return blms.getNumberOfMatches(playerID, leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.addMatchResult</code>
	 * @return 
	 * @throws ParseException 
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.addMatchResult
	 */
	public int addMatchResult(String leagueId, String date, String winnerID, String loserID) throws ParseException, RestrictionException {
		return blms.addMatchResult(leagueId, blms.getDateFormat().parse(date), winnerID, loserID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.addMatchResult</code>
	 * @return 
	 * @throws ParseException 
	 * @throws RestrictionException 
	 * @throws NumberFormatException 
	 * 
	 * @see BLMS.addMatchResult
	 */
	public int addMatchResult(String leagueId, String date, String winnerID, String loserID, String length,
								String score, String longestRunForWinner, String longestRunForLoser) throws ParseException,
																													RestrictionException {
		
		return blms.addMatchResult(leagueId, blms.getDateFormat().parse(date), winnerID, loserID, length,
										score, longestRunForWinner, longestRunForLoser);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.updateMatchResult</code>
	 * @throws ParseException 
	 * @throws NumberFormatException 
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.updateMatchResult
	 */
	public void updateMatchResult(int matchID, String date, String winnerID, String loserID, String length,
									String score, String longestRunForWinner, String longestRunForLoser) throws NumberFormatException, ParseException, RestrictionException {
		
		blms.updateMatchResult(matchID, blms.getDateFormat().parse(date), winnerID, loserID, 
								Integer.parseInt(length), Integer.parseInt(score), Integer.parseInt(longestRunForWinner), 
									Integer.parseInt(longestRunForLoser));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getNumberOfWins</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getNumberOfWins
	 */
	public int getNumberOfWins(String playerID, String leagueID) throws RestrictionException {
		return blms.getNumberOfWins(playerID, leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getNumberOfLosses</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getNumberOfLosses
	 */
	public int getNumberOfLosses(String playerID, String leagueID) throws RestrictionException {
		return blms.getNumberOfLosses(playerID, leagueID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatch</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatch
	 */
	public int getMatch(String leagueID, int index) throws RestrictionException {
		return blms.getMatch(leagueID, index);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatch</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatch
	 */
	public int getMatch(String playerID, String leagueID, int index) throws RestrictionException {
		return blms.getMatch(playerID, leagueID, index);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchByDate</code>
	 * @throws ParseException 
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatchByDate
	 */
	public int getMatchByDate(String leagueID, String startDate, String endDate, int index) throws ParseException, RestrictionException {
		return blms.getMatchByDate(leagueID, blms.getDateFormat().parse(startDate), blms.getDateFormat().parse(endDate), index);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchByDate</code>
	 * @throws ParseException 
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatchByDate
	 */
	public int getMatchByDate(String playerID, String leagueID, String startDate, String endDate, int index) throws ParseException, RestrictionException {
		return blms.getMatchByDate(playerID, leagueID, blms.getDateFormat().parse(startDate), blms.getDateFormat().parse(endDate), index);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatch</code>
	 * 
	 * @see BLMS.getMatch
	 */
	public String getMatchDate(String matchID) {
		return blms.getMatchDate(Integer.parseInt(matchID));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchWinner</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatchWinner
	 */
	public String getMatchWinner(String matchID) throws RestrictionException {
		return blms.getMatchWinner(matchID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchLoser</code>
	 * @throws RestrictionException 
	 * 
	 * @see BLMS.getMatchLoser
	 */
	public String getMatchLoser(String matchID) throws RestrictionException {
		return blms.getMatchLoser(matchID);
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchLength</code>
	 * 
	 * @see BLMS.getMatchLength
	 */
	public String getMatchLength(String matchID) {
		return blms.getMatchLength(Integer.parseInt(matchID));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchScore</code>
	 * 
	 * @see BLMS.getMatchScore
	 */
	public String getMatchScore(String matchID) {
		return blms.getMatchScore(Integer.parseInt(matchID));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchLongestRunForWinner</code>
	 * 
	 * @see BLMS.getMatchLongestRunForWinner
	 */
	public String getMatchLongestRunForWinner(String matchID) {
		return blms.getMatchLongestRunForWinner(Integer.parseInt(matchID));
	}
	
	/**
	 * EasyAccept facade for <code>BLMS.getMatchLongestRunForLoser</code>
	 * 
	 * @see BLMS.getMatchLongestRunForLoser
	 */
	public String getMatchLongestRunForLoser(String matchID) {
		return blms.getMatchLongestRunForLoser(Integer.parseInt(matchID));
	}
	
	/**
	 * @return
	 */
	public String todaysDate() {
	    return blms.getDateFormat().format(new Date());
	}
	
	public void dateFormat(String format) {
		blms.setDateFormat(new SimpleDateFormat(format));
	}
}